import threading
import socket
import os
import sys
import datetime
from flask import Flask, request, render_template_string, send_from_directory

app = Flask(__name__)
UPLOAD_FOLDER = 'content'
os.makedirs(UPLOAD_FOLDER, exist_ok=True)

def get_local_ip():
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        ip = s.getsockname()[0]
        s.close()
        return ip
    except Exception:
        return "127.0.0.1"

def is_port_free(port):
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
        return s.connect_ex(('127.0.0.1', port)) != 0

def find_free_port(start=9090):
    port = start
    while port < 65535:
        if is_port_free(port):
            return port
        port += 1
    raise OSError("No free port found between 9090-65534")

LOCAL_IP = get_local_ip()
PORT = find_free_port(9090)
BASE_URL = f"http://{LOCAL_IP}:{PORT}"
LOCAL_URL = f"http://127.0.0.1:{PORT}"

HTML_TEMPLATE = '''
<!DOCTYPE html>
<html lang="zh">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>📦 资料共享盒</title>
    <style>
        :root {
            --bg: #f8f9fa;
            --card-bg: #ffffff;
            --text: #212529;
            --accent: #007bff;
            --border: #dee2e6;
            --shadow: 0 2px 10px rgba(0, 0, 0, 0.08);
        }
        @media (prefers-color-scheme: dark) {
            :root {
                --bg: #121212;
                --card-bg: #1e1e1e;
                --text: #e0e0e0;
                --accent: #0066ff;
                --border: #333333;
                --shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
            }
        }
        * {
            box-sizing: border-box;
            margin: 0;
            padding: 0;
        }
        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
            background: var(--bg);
            color: var(--text);
            line-height: 1.6;
            padding: 16px;
            transition: background 0.3s, color 0.3s;
        }
        .container {
            max-width: 900px;
            margin: 0 auto;
        }
        header {
            text-align: center;
            margin-bottom: 32px;
        }
        .upload-card {
            background: var(--card-bg);
            border-radius: 12px;
            padding: 24px;
            box-shadow: var(--shadow);
            border: 1px solid var(--border);
            margin-bottom: 40px;
            transition: box-shadow 0.3s;
        }
        input[type="text"], input[type="url"], textarea {
            width: 100%;
            padding: 12px;
            border: 1px solid var(--border);
            border-radius: 8px;
            background: var(--card-bg);
            color: var(--text);
            font-size: 1rem;
            margin: 6px 0;
        }
        .input-group {
            margin: 16px 0;
        }
        input[type="file"] {
            border: 1px dashed var(--border);
            padding: 12px;
            border-radius: 8px;
            background: var(--bg);
            width: 100%;
        }
        button {
            margin-top: 16px;
            padding: 12px 24px;
            background: var(--accent);
            color: white;
            border: none;
            border-radius: 8px;
            font-size: 1rem;
            cursor: pointer;
            font-weight: 600;
            transition: background 0.2s;
        }
        .files {
            margin-top: 20px;
        }
        .file-list {
            list-style: none;
        }
        .file-item {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 14px 16px;
            background: var(--card-bg);
            border: 1px solid var(--border);
            border-radius: 8px;
            margin-bottom: 12px;
            transition: transform 0.1s, box-shadow 0.2s;
        }
        .file-name {
            font-weight: 500;
            color: var(--accent);
            word-break: break-all;
            text-decoration: none;
        }
        .file-meta {
            font-size: 0.85rem;
            opacity: 0.7;
            margin-top: 4px;
        }
        .file-actions {
            display: flex;
            gap: 10px;
        }
        .btn-copy {
            background: #6c757d;
            color: white;
            border: none;
            cursor: pointer;
        }
        .btn-copy:hover { background: #5a6268; }
        .btn-copy.copied {
            background: #28a745;
            opacity: 0.8;
        }
    </style>
</head>
<body>
    <div class="container">
        <header>
            <h1>📦 资料共享盒</h1>
            <p>上传文件、文本或链接，支持自定义命名与一键复制分享链接</p>
        </header>

        <div class="upload-card">
            <h2>📤 上传内容</h2>
            <form method="POST" enctype="multipart/form-data">
                <div class="input-group">
                    <label>📷 上传文件（可选命名）</label>
                    <input type="file" name="file" accept="image/*,text/plain">
                    <input type="text" name="custom_filename" placeholder="自定义文件名（如：会议记录.jpg），留空则自动命名">
                </div>

                <div class="input-group">
                    <label>📄 输入文本内容（可选命名）</label>
                    <textarea name="text_content" placeholder="输入文字..."></textarea>
                    <input type="text" name="text_filename" placeholder="保存为（如：笔记.txt），默认：text_时间.txt">
                </div>

                <div class="input-group">
                    <label>🔗 添加网页链接（可选命名）</label>
                    <input type="text" name="link_title" placeholder="链接标题">
                    <input type="url" name="link_url" placeholder="https://example.com">
                    <input type="text" name="link_filename" placeholder="保存为（如：我的博客.url），默认自动生成">
                </div>

                <button type="submit">✅ 立即上传</button>
            </form>
        </div>

        <div class="files">
            <h2>📂 已保存内容</h2>
            {% if files %}
            <ul class="file-list">
                {% for f in files %}
                <li class="file-item">
                    <div class="file-info">
                        <a href="/content/{{ f }}" target="_blank" class="file-name">
                            {% if f.endswith('.url') %}
                            🔗 {{ titles[f] }}
                            {% elif f.startswith('text_') and f.endswith('.txt') %}
                            📄 {{ f }}
                            {% else %}
                            🖼️ {{ f }}
                            {% endif %}
                        </a>
                        <div class="file-meta">{{ sizes[f] }} • {{ dates[f] }}</div>
                    </div>
                    <div class="file-actions">
                        {% if f.endswith('.url') %}
                        <a href="/content/{{ f }}" class="icon" title="打开">↗️</a>
                        {% else %}
                        <a href="/content/{{ f }}" download class="icon" title="下载">⬇️</a>
                        {% endif %}
                        <button class="btn-copy" data-url="{{ share_urls[f] }}" title="复制分享链接">📋 复制</button>
                    </div>
                </li>
                {% endfor %}
            </ul>
            {% else %}
            <p style="color: var(--text); opacity: 0.6; text-align: center; padding: 20px; background: var(--card-bg); border-radius: 8px;">📂 还没有上传任何内容</p>
            {% endif %}
        </div>
    </div>

    <script>
        document.querySelectorAll('.btn-copy').forEach(btn => {
            btn.addEventListener('click', () => {
                const url = btn.getAttribute('data-url');
                if (navigator.clipboard && typeof navigator.clipboard.writeText !== 'undefined') {
                    navigator.clipboard.writeText(url).then(() => {
                        btn.textContent = '✅ 已复制';
                        btn.classList.add('copied');
                        setTimeout(() => {
                            btn.textContent = '📋 复制';
                            btn.classList.remove('copied');
                        }, 2000);
                    }).catch(err => {
                        console.warn('Clipboard API 失败:', err);
                        fallbackCopy(url, btn);
                    });
                } else {
                    fallbackCopy(url, btn);
                }
            });
        });

        function fallbackCopy(text, button) {
            const textarea = document.createElement("textarea");
            textarea.value = text;
            textarea.style.position = "fixed";
            textarea.style.opacity = "0";
            document.body.appendChild(textarea);
            textarea.focus();
            textarea.select();
            try {
                document.execCommand("copy");
                button.textContent = "✅ 已复制";
                button.classList.add('copied');
                setTimeout(() => {
                    button.textContent = "📋 复制";
                    button.classList.remove('copied');
                }, 2000);
            } catch (err) {
                alert("复制失败，请手动复制:\\n" + text);
            } finally {
                document.body.removeChild(textarea);
            }
        }
    </script>
</body>
</html>
'''

@app.route('/', methods=['GET', 'POST'])
def index():
    if request.method == 'POST':
        if 'file' in request.files and request.files['file'].filename:
            file = request.files['file']
            ext = file.filename.rsplit('.', 1)[-1].lower()
            custom_name = request.form.get('custom_filename', '').strip()
            if custom_name:
                filename = custom_name if custom_name.endswith(f'.{ext}') else f"{custom_name}.{ext}"
            else:
                basename = "img" if file.content_type.startswith("image/") else "file"
                filename = f"{datetime.date.today().strftime('%Y-%m-%d')}_{basename}_1.{ext}"
            file.save(os.path.join(UPLOAD_FOLDER, filename))

        text = request.form.get('text_content', '').strip()
        if text:
            custom_name = request.form.get('text_filename', '').strip()
            if custom_name:
                filename = custom_name if custom_name.endswith('.txt') else f"{custom_name}.txt"
            else:
                filename = f"{datetime.date.today().strftime('%Y-%m-%d')}_text_1.txt"
            with open(os.path.join(UPLOAD_FOLDER, filename), 'w', encoding='utf-8') as f:
                f.write(text + '\n')

        link_title = request.form.get('link_title', '').strip()
        link_url = request.form.get('link_url', '').strip()
        if link_title and link_url:
            custom_name = request.form.get('link_filename', '').strip()
            if custom_name:
                filename = custom_name if custom_name.endswith('.url') else f"{custom_name}.url"
                html_name = f"goto_{custom_name}.html"
            else:
                filename = f"{datetime.date.today().strftime('%Y-%m-%d')}_link_1.url"
                html_name = f"goto_{filename}.html"

            with open(os.path.join(UPLOAD_FOLDER, filename), 'w', encoding='utf-8') as f:
                f.write(f"[InternetShortcut]\nURL={link_url}\n")

            with open(os.path.join(UPLOAD_FOLDER, html_name), 'w', encoding='utf-8') as f:
                f.write(f'''
                <meta http-equiv="refresh" content="0;url={link_url}">
                <script>setTimeout(() => window.location.href = "{link_url}", 0);</script>
                <p>正在跳转到: <a href="{link_url}">{link_title}</a></p>
                ''')

        return redirect(url_for('index'))

    files = [f for f in os.listdir(UPLOAD_FOLDER) if os.path.isfile(os.path.join(UPLOAD_FOLDER, f))]
    files.sort(key=lambda x: os.path.getmtime(os.path.join(UPLOAD_FOLDER, x)), reverse=True)

    def sizeof_fmt(num):
        for unit in ['B', 'KB', 'MB']:
            if num < 1024.0:
                return f"{num:.1f}{unit}"
            num /= 1024.0
        return f"{num:.1f}GB"

    sizes = {f: sizeof_fmt(os.path.getsize(os.path.join(UPLOAD_FOLDER, f))) for f in files}
    dates = {f: datetime.datetime.fromtimestamp(os.path.getmtime(os.path.join(UPLOAD_FOLDER, f))).strftime("%m-%d %H:%M") for f in files}
    titles = {}
    for f in files:
        if f.endswith('.url'):
            try:
                with open(os.path.join(UPLOAD_FOLDER, f), 'r', encoding='utf-8') as ff:
                    for line in ff:
                        if line.lower().startswith('url='):
                            titles[f] = line[4:].strip()
                            break
            except:
                titles[f] = "🔗 无效链接"

    share_urls = {f: f"{BASE_URL}/content/{f}" for f in files}

    return render_template_string(
        HTML_TEMPLATE,
        files=files,
        sizes=sizes,
        dates=dates,
        titles=titles,
        share_urls=share_urls
    )

@app.route('/content/<filename>')
def download_file(filename):
    file_path = os.path.join(UPLOAD_FOLDER, filename)
    if not os.path.exists(file_path):
        return "文件不存在", 404
    return send_from_directory(UPLOAD_FOLDER, filename)

if __name__ == '__main__':
    from werkzeug.serving import make_server

    class FlaskThread(threading.Thread):
        def __init__(self, app, host, port):
            super().__init__()
            self.daemon = True
            self.server = make_server(host, port, app)
            self.ctx = app.app_context()
            self.ctx.push()

        def run(self):
            print(f"Server starting on port {PORT}")
            self.server.serve_forever()

        def shutdown(self):
            self.server.shutdown()

    server = FlaskThread(app, '0.0.0.0', PORT)
    server.start()

    print(f"🚀 资料共享盒 启动中...")
    print(f"   将在 {PORT} 端口启动服务")
    print(f"   本地访问: {LOCAL_URL}")
    print(f"   局域网访问: {BASE_URL}")
    print(f"   文件保存在: {os.path.abspath(UPLOAD_FOLDER)}")
    print(f"   按 Ctrl+C 停止服务")

    try:
        while True:
            # Keep the main thread alive to handle signals
            import time
            time.sleep(1)
    except KeyboardInterrupt:
        print("\nStopping server...")
        server.shutdown()
        sys.exit(0)